package Nionetwork;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;//nio网络编程包，和tcp差不多
import java.util.Set;
import java.util.Iterator;
//nio类似于tcp/udp通讯模式，好似这两个的升级版
public class NioServer {
    public static void main(String [] d) throws IOException
    {



        int port=8001;//定义端口号
        Selector selector=null;//定义一个通道选择器
        ServerSocketChannel serverChannel=null;//服务器端的通道
        //客户端的通道用SocketChannel
        try
        {//服务器初始化
            selector=Selector.open();//通道选择器打开
            serverChannel=ServerSocketChannel.open();//服务端的通讯管道打开
            serverChannel.configureBlocking(false);//把服务器端通道配置成非阻塞模式
            serverChannel.socket().bind(new InetSocketAddress(port),1024);//服务器驻守在8001端口等待客户端消息
            serverChannel.register(selector,SelectionKey.OP_ACCEPT);//把服务器和通道选择器进行绑定，这样选择器就能监控着所有的通道的其他服务器
            System.out.println("服务器正在8001端口守候....");
        }catch(Exception e)
        {e.printStackTrace();
        System.exit(1);}

        while(true)
        {
            try{
                selector.select(1000);//每隔一秒钟选择一次
                Set<SelectionKey> selectedKeys=selector.selectedKeys();//获取所有有数据响应的Channel
                Iterator<SelectionKey> it=selectedKeys.iterator();//对所有的数据进行遍历
                SelectionKey key=null;
                while(it.hasNext())//如果遍历中有数据则进行输出
                {
                    key=it.next();
                    it.remove();
                    try
                    {
                        handleInput(selector,key);//交给这个函数去处理
                    }catch(Exception e){e.printStackTrace();}
                }
            }catch(Exception e)
            {e.printStackTrace();}
        }

    }
    public static void handleInput(Selector selector,SelectionKey key) throws IOException
    {
        if (key.isValid())
        {
            if (key.isAcceptable())
            {
                ServerSocketChannel ssc=(ServerSocketChannel) key.channel();
                SocketChannel sc=ssc.accept();
                sc.configureBlocking(false);//把通道配置成非阻塞模式
                sc.register(selector,SelectionKey.OP_READ);//服务器端是绑定注册选择器
            }
            if (key.isReadable())
            {
                SocketChannel sc = (SocketChannel) key.channel();
                ByteBuffer readBuffer = ByteBuffer.allocate(1024);
                int readBytes = sc.read(readBuffer);
                if (readBytes > 0) {
                    readBuffer.flip();
                    byte[] bytes = new byte[readBuffer.remaining()];
                    readBuffer.get(bytes);
                    String request = new String(bytes, "UTF-8"); //接收到的输入
                    System.out.println("客户端说: " + request);

                    String response = request + "服务器回应： 666";
                    doWrite(sc, response);
                } else if (readBytes < 0) {
                    // 对端链路关闭
                    key.cancel();
                    sc.close();
                } else
                {;}

            }
        }
    }
    public static void doWrite(SocketChannel channel, String response) throws IOException {
        if (response != null && response.trim().length() > 0) {
            byte[] bytes = response.getBytes();
            ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
            writeBuffer.put(bytes);
            writeBuffer.flip();
            channel.write(writeBuffer);
        }
    }
}
